home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / PeerAware 1.03 / PeerAware-Setup.exe / Html / scripts / svgrenderer.js < prev    next >
Text File  |  2008-01-06  |  57KB  |  2,019 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Cumulate Draw SVG Renderer.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Cumulate Labs Inc.
  18.  * Portions created by Cumulate Labs Inc. are Copyright (C) 2006-2007
  19.  * Cumulate Labs Inc. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25.  * in which case the provisions of the LGPL are applicable instead
  26.  * of those above. If you wish to allow use of your version of this file only
  27.  * under the terms of the LGPL, and not to allow others to
  28.  * use your version of this file under the terms of the MPL, indicate your
  29.  * decision by deleting the provisions above and replace them with the notice
  30.  * and other provisions required by the LGPL. If you do not delete
  31.  * the provisions above, a recipient may use your version of this file under
  32.  * the terms of any one of the MPL or the LGPL.
  33.  *
  34.  * ***** END LICENSE BLOCK ***** */
  35.  
  36.  
  37. /*----------------------------------------------------------------------------
  38.  SVGRENDERER 0.1
  39.  SVG Renderer For cumulate draw (http://www.cumulatelabs.com)
  40.  History:
  41.  2006-10-19 | created
  42.  */
  43.  
  44. /**********************************BEGIN INITIALIZATION FUNCTIONS******************************/
  45. function SVGRenderer() {
  46.     this.base = AbstractRenderer;
  47.     this.svgRoot = null;
  48. }
  49.  
  50.  
  51. SVGRenderer.prototype = new AbstractRenderer;
  52.  
  53.  
  54. SVGRenderer.prototype.init = function(elem) {
  55.   this.MAX_HEIGHT=2000;
  56.   this.MAX_WIDTH=2000;
  57.   this.COORD_X=1000;//ALL shapes are defined in 1000x1000 coord space
  58.   this.COORD_Y=1000;
  59.   this.CONNECTOR_TAG="svg:connector";
  60.   this.TEXT_TEMPLATE_PREFIX="text:template";
  61.   this.LINE_DELIMITER="\n";
  62.   this.GRADIENT_PREFIX="GRADIENT";
  63.   this.MARKER_BEGIN_PREFIX="MARKER_START";
  64.   this.MARKER_END_PREFIX="MARKER_END";
  65.    this.EXTENSION='fmd';
  66.   this.TYPE="SVG";
  67.   this.container = elem;
  68.   this.svgNamespace = 'http://www.w3.org/2000/svg';
  69.   this.cumulateNamespace="urn:schemas-cumulatelabs-com:svg";
  70.   this.xmlNamespace="http://www.w3.org/2001/xml";
  71.   this.svgRoot = this.container.ownerDocument.createElementNS(this.svgNamespace, "svg");
  72.   this.svgRoot.setAttribute("xml:space","preserve");
  73.   this.LONG_DASH="7,3";
  74.   this.SHORT_DASH="4,3";
  75.   var shadow=this.loadShape('shadow','defs');
  76.     
  77.   this.svgRoot.style.position="absolute";
  78.   this.svgRoot.style.zIndex=10;
  79.   this.svgRoot.setAttributeNS(null, 'x','0px');
  80.   this.svgRoot.setAttributeNS(null, 'y', '0px');
  81.   this.svgRoot.setAttributeNS(null, 'width',this.MAX_WIDTH+'px');
  82.   this.svgRoot.setAttributeNS(null, 'height',this.MAX_HEIGHT+'px'); 
  83.   
  84.   var firstChild=this.container.firstChild;
  85.   this.svgRoot.style.MozUserSelect = 'none';
  86.   this.minIndex=200;
  87.   this.maxIndex=200;
  88.   this.container.insertBefore(this.svgRoot,firstChild);
  89.   this.svgRoot.appendChild(shadow);
  90.  
  91. }
  92.  
  93. /****************************************************END INITIALIZATION FUNCTIONS**************************************/
  94.  
  95. /**
  96. *return the current bounds of the shape
  97. **/
  98. SVGRenderer.prototype.bounds = function(shape) {
  99.   if(!shape)return
  100.   var rect = { x:0, y:0, width:0, height: 0,rotation:0,x2:0,y2:0,id:0,type:"",controlX:0,controlY:0,controlX2:0,controlY2:0 };
  101.   rect['id']=shape.getAttributeNS(null,"id");
  102.   if(this.isConnector(shape))
  103.   {
  104.       rect['x']=this.getConnectorFromX(shape);
  105.       rect['y']=this.getConnectorFromY(shape);
  106.       rect['x2']=this.getConnectorToX(shape);
  107.       rect['y2']=this.getConnectorToY(shape);
  108.       rect['type']=this.getConnectorType(shape);
  109.       if(rect.type=='curve-line'){
  110.           var obj1=this.getControl1(shape);
  111.           var obj2=this.getControl2(shape);
  112.           rect['controlX']=obj1.x;
  113.           rect['controlY']=obj1.y;
  114.           rect['controlX2']=obj2.x;
  115.           rect['controlY2']=obj2.y;
  116.       }
  117.       
  118.   }
  119.   else{
  120.       rect['rotation']=this.getRotation(shape);
  121.       if(!rect['rotation'])
  122.         rect['rotation']=0;
  123.       rect['x'] = this.getX(shape);
  124.       rect['y'] = this.getY(shape);
  125.       rect['width'] = this.getWidth(shape);
  126.       rect['height'] = this.getHeight(shape);
  127.  
  128.   }
  129.   return rect;
  130. }
  131.  
  132. /*************************BEGIN SHAPE CREATION FUNCTIONS****************************/
  133. /**
  134. *load an xml shape for creation-
  135. *TODO we will have to add some error handling later on
  136. */
  137.  
  138. SVGRenderer.prototype.loadShape=function(shapeID,retrieveTag){
  139.     objValidXMLFile=this.loadXML("shapes/svg/"+shapeID+".xml");
  140.     var nodeList=objValidXMLFile.getElementsByTagName(retrieveTag);
  141.     if(retrieveTag){
  142.       var node=nodeList[0];
  143.       return node;
  144.     }
  145.  
  146. }
  147. SVGRenderer.prototype.loadXML=function(path){
  148.     var objValidXMLFile =  document.implementation.createDocument(null, null, null); 
  149.     objValidXMLFile.async=false;
  150.     objValidXMLFile.load(path);
  151.     return objValidXMLFile;
  152.  
  153. }
  154. /**
  155. * create a line shape
  156. **/
  157. SVGRenderer.prototype.createLine=function(shape,lineColor,lineWidth,left,top,lineStyle){
  158.     
  159.     var svg=this.loadShape(shape,"g");
  160.       this.svgRoot.appendChild(svg);
  161.       if(shape=='line'||shape=='curve-line'){
  162.            this.setLineFrom(svg,left,top);
  163.            this.setLineTo(svg,left,top);
  164.        }
  165.        if(shape=='curve-line'){
  166.            this.setControl1(svg,left,top);
  167.            this.setControl2(svg,left,top);
  168.        }
  169.        var markers=this.getMarkers(svg);
  170.        markers[0].id=this.MARKER_BEGIN_PREFIX+createUUID();
  171.        markers[1].id=this.MARKER_END_PREFIX+createUUID();
  172.        this.setZIndex(svg,this.maxIndex++);
  173.        
  174.        return svg;
  175. }
  176.  
  177. /**
  178. *all svg shapes are in the format g/svg/path in addition filters for linear gradient, line stroke may be added
  179. **/
  180. SVGRenderer.prototype.create = function(shape, fillColor, lineColor, lineWidth, left, top, width, height) {
  181.   var svg=this.loadShape(shape,"g");
  182.   this.svgRoot.appendChild(svg);
  183.    this.setX(svg,left);
  184.    this.setY(svg,top);
  185.    this.setWidth(svg,width);
  186.    this.setHeight(svg,height);
  187.    this.setZIndex(svg,this.maxIndex++);
  188.    this.fixLinearGradientID(svg);
  189.    //now fix the shape to match its linear gradient!
  190.   // var isGradient=this.getLinearGradient(svg);
  191.   // if(isGradient)this.setLinearGradient(svg,true);
  192.   // this.setFillColor(svg,this.getFillColor(svg));
  193.  
  194.    
  195.    return svg;
  196. };
  197. /**
  198. *utility function to create and element based on namespace constants 
  199. **/
  200. SVGRenderer.prototype.createElement=function(elementTag,namespace){
  201.     if(namespace=='CUMULATE_LABS'){
  202.         return this.container.ownerDocument.createElementNS(this.cumulateNamespace,elementTag);
  203.     }
  204.     else{
  205.         return this.container.ownerDocument.createElementNS(this.svgNamespace,elementTag);
  206.     }
  207.  
  208.  
  209. }
  210.  
  211. /**
  212. * a utitlity function to return an attribute in IE specific manner,assumes that element
  213. * is not null!
  214. **/
  215. SVGRenderer.prototype.getAttribute=function(element,attribute){
  216.     return element.getAttributeNS(null,attribute);
  217.  
  218. }
  219.  
  220. /**
  221. * clone the node
  222. **/
  223. SVGRenderer.prototype.copy=function(shape){
  224.     if(!shape)return null;
  225.     return  shape.cloneNode(true);
  226.  
  227. }
  228.  
  229. /**
  230. *add the cloned node
  231. **/
  232. SVGRenderer.prototype.paste=function(shape){
  233.         if(!shape)return;
  234.         var node=shape;
  235.         node.id='shape:' + createUUID();
  236.         var svg=node.getElementsByTagName("svg");
  237.         if(svg.length>0)
  238.             svg.item(0).id='shape:'+createUUID();
  239.         var text=node.getElementsByTagName("text")
  240.         for(var i=0;i<text.length;i++){
  241.             var textItem=text.item(i);
  242.             if(textItem.id.indexOf(this.TEXT_TEMPLATE_PREFIX)>=0){
  243.                 textItem.id=this.TEXT_TEMPLATE_PREFIX+node.id;
  244.             }
  245.         }
  246.     
  247.         if(!this.isConnector(node)){
  248.             var x=this.getX(node);
  249.             var y=this.getY(node);
  250.             this.setX(node,(x*1)+10);
  251.             this.setY(node,(y*1)+10);
  252.             //update the gradient;
  253.             this.fixLinearGradientID(node);
  254.         }
  255.         if(this.isConnector(node)){
  256.             var markers=this.getMarkers(node);
  257.             markers[0].id=this.MARKER_BEGIN_PREFIX+createUUID();
  258.                markers[1].id=this.MARKER_END_PREFIX+createUUID();
  259.                var lineStyle=this.getLineStyle(node);
  260.                this.setLineStyle(node,lineStyle);
  261.         
  262.         }
  263.         //now null any connections
  264.         var connectList=node.getElementsByTagName("connection");
  265.         var array=new Array();
  266.         for(var i=0;i<connectList.length;i++){
  267.             //if its a line emtpy it
  268.             if(this.isConnector(node)){
  269.                 connectList.item(i).setAttribute("shapeid","xx");
  270.                 connectList.item(i).setAttribute("shapepoint","-1");
  271.             }
  272.             //if its a shape remove it!
  273.             else{
  274.              array[i]=connectList.item(i);
  275.             }
  276.         }
  277.         for(var i=0;i<array.length;i++){
  278.             this.remove(array[i]);
  279.         }
  280.         //append automatically brings the shape to the front for svg
  281.         this.svgRoot.appendChild(node);
  282.         return node;
  283. }
  284.  
  285.  
  286. /*************************END SHAPE CREATION FUNCTIONS****************************/
  287. /**
  288. *indicate if a shape is a connector
  289. **/
  290. SVGRenderer.prototype.isConnector=function(shape){
  291.     if(shape)
  292.         return (shape.getElementsByTagName("connector").length>0);
  293.     else
  294.         return false;
  295. }
  296.  
  297. /*************************ZINDEX FUNCTIONS************************/
  298. /**
  299. *set the shape ZIndex, this method does nothing since svg does not support zindexes
  300. *@see http://wiki.svg.org/Rendering_Order
  301. *@param shape
  302. *@param zIndex;
  303. **/
  304. SVGRenderer.prototype.setZIndex=function(shape,zIndex){
  305.     if(shape){
  306.         shape.setAttributeNS(null,"z-index",zIndex);
  307.     }
  308. }
  309. /**
  310. *get the shape zIndex, this method is just informational, since svg does not support zindexes
  311. *@see http://wiki.svg.org/Rendering_Order
  312. *@param shape
  313. *@return zIndex
  314. **/
  315. SVGRenderer.prototype.getZIndex=function(shape){
  316.     if(shape)
  317.         return shape.getAttributeNS(null,"z-index");
  318. }
  319.  
  320. /**
  321. * send to back
  322. *@param the shape
  323. **/
  324. SVGRenderer.prototype.sendToBack=function(shape){
  325.     if(shape){
  326.         var node =shape.cloneNode(true);
  327.         this.remove(shape);
  328.         this.svgRoot.insertBefore(node,this.svgRoot.firstChild);
  329.         this.setZIndex(node,this.minIndex--);
  330.         return node;
  331.     }
  332. }
  333.  
  334. /**
  335. * Bring to Front
  336. *@param the shape
  337. **/
  338. SVGRenderer.prototype.bringToFront=function(shape){
  339.     if(shape){
  340.         var node =shape.cloneNode(true);
  341.         this.remove(shape);
  342.         this.svgRoot.appendChild(node);
  343.         this.setZIndex(node,this.maxIndex++);
  344.         return node;
  345.     }
  346. }
  347.  
  348. /*************************LINE FUNCTIONS***********************/
  349. /**
  350. *set the line from
  351. **/
  352. SVGRenderer.prototype.setLineFrom=function(shape,fromX,fromY){
  353.     var subject=this.getShapeSubject(shape);
  354.     var type=this.getConnectorType(shape);
  355.     if(type=='line'){
  356.         subject.setAttributeNS(null,"x1",fromX);
  357.         subject.setAttributeNS(null,"y1",fromY);
  358.     }
  359.     else if(type=='curve-line'){
  360.         var path=subject.pathSegList;
  361.         var pathItem=path.getItem(0);
  362.         pathItem.x=fromX;
  363.         pathItem.y=fromY;
  364.     }
  365.  
  366.  
  367. }
  368. /**
  369. *set the line to
  370. **/
  371. SVGRenderer.prototype.setLineTo=function(shape,toX,toY){
  372.     var subject=this.getShapeSubject(shape);
  373.     var type=this.getConnectorType(shape);
  374.     if(type=='line'){
  375.         subject.setAttributeNS(null,"x2",toX);
  376.         subject.setAttributeNS(null,"y2",toY);
  377.     }
  378.     else if(type=='curve-line'){
  379.         var path=subject.pathSegList;
  380.         var pathItem=path.getItem(1);
  381.         pathItem.x=toX;
  382.         pathItem.y=toY;
  383.     }
  384.  
  385. }
  386. /**
  387. * set control point 1
  388. **/
  389. SVGRenderer.prototype.setControl1=function(shape,toX,toY){
  390.     var subject=this.getShapeSubject(shape);
  391.     var path=subject.pathSegList;
  392.     var pathItem=path.getItem(1);
  393.     pathItem.x1=toX;
  394.     pathItem.y1=toY;
  395.  
  396.  
  397. }
  398.  
  399. /**
  400. * set control point 1
  401. **/
  402. SVGRenderer.prototype.getControl1=function(shape){
  403.     var subject=this.getShapeSubject(shape);
  404.     var path=subject.pathSegList;
  405.     var pathItem=path.getItem(1);
  406.     var obj=new Object();
  407.     obj.x=pathItem.x1;
  408.     obj.y=pathItem.y1;
  409.     return obj;
  410.  
  411. }
  412.  
  413.  
  414. /**
  415. * set control point 1
  416. **/
  417. SVGRenderer.prototype.setControl2=function(shape,toX,toY){
  418.     var subject=this.getShapeSubject(shape);
  419.     var path=subject.pathSegList;
  420.     var pathItem=path.getItem(1);
  421.     pathItem.x2=toX;
  422.     pathItem.y2=toY;
  423.  
  424.  
  425. }
  426.  
  427. /**
  428. * set control point 1
  429. **/
  430. SVGRenderer.prototype.getControl2=function(shape){
  431.     var subject=this.getShapeSubject(shape);
  432.     var path=subject.pathSegList;
  433.     var pathItem=path.getItem(1);
  434.     var obj=new Object();
  435.     obj.x=pathItem.x2;
  436.     obj.y=pathItem.y2;
  437.     return obj;
  438.  
  439. }
  440.  
  441.  
  442.  
  443.  
  444. /**
  445. *simply for compatibility reasons, the vml version converts pixels to points in this method, 
  446. *svg version does not need that
  447. **/
  448. SVGRenderer.prototype.moveLinePoint=function(shape,toX,toY,isFrom){
  449.     this.moveLine(shape,toX,toY,isFrom);
  450. }
  451. /**
  452. *move line or polyline
  453. **/
  454. SVGRenderer.prototype.moveLine=function(shape,toX,toY, isFrom){
  455.     if(!shape||!this.isConnector(shape)){
  456.         return;
  457.     }
  458.     var type=this.getConnectorType(shape);
  459.     if(type=='line'||type=='curve-line'){
  460.         if(isFrom){
  461.             this.setLineFrom(shape,toX,toY);
  462.         }
  463.         else{
  464.             this.setLineTo(shape,toX,toY);
  465.         }
  466.     }
  467.     else{
  468.         var subject =shape.getElementsByTagName("polyline")[0];
  469.         var points=subject.points;
  470.         var length=points.numberOfItems;
  471.         if(isFrom){
  472.             
  473.             var x=points.getItem(length-1).x;
  474.             var y=points.getItem(length-1).y;
  475.             this.drawOrthoLine(shape,toX,toY,x,y);
  476.         }
  477.         else{
  478.             var x=points.getItem(0).x;
  479.             var y=points.getItem(0).y;
  480.             this.drawOrthoLine(shape,x,y,toX,toY);
  481.         }
  482.     }
  483.         
  484. }
  485. /**********************************************BEGIN ORTHO-LINE DRAW FUNCTIONS**************************/
  486. /**
  487.  * get the segments of the orthogonal connector--get the central segment, 
  488.  * @return {object} containing x,y,x2,y2
  489.  */
  490. SVGRenderer.prototype.getOrthoLineCenterSegment=function(shape){
  491.     //debugger;
  492.     var obj=new Object();
  493.     var points=this.getShapeSubject(shape).points;
  494.     
  495.     //get the center point
  496.     var centerPoint=Math.round(points.numberOfItems/2-1);
  497.     var center=points.getItem(centerPoint);
  498.     var before=points.getItem(centerPoint-1);
  499.     var after=points.getItem(centerPoint+1);
  500.     var distanceA=((center.y-before.y)*(center.y-before.y))+((center.x-before.x)*(center.x-before.x));
  501.     var distanceB=((center.y-after.y)*(center.y-after.y))+((center.x-after.x)*(center.x-after.x));
  502.     var referencePoint=distanceA>distanceB?before:after;
  503.     obj.x=referencePoint.x;
  504.     obj.y=referencePoint.y;
  505.     obj.x2=center.x;
  506.     obj.y2=center.y;
  507.     return obj;
  508. }
  509. /*
  510. *special method to draw orthogonal lines. first calculate the horizontal distance, then calculate the vertical distance, 
  511. * if horizontal< vertical, split horizontal in 1/2 and vice versa, set this in the shape
  512. */
  513. SVGRenderer.prototype.drawOrthoLine= function(shape,fromX,fromY,toX,toY){
  514.     var path=this.calculateOrthoLinePath(shape,fromX,fromY,toX,toY);
  515.     var polyline=this.getShapeSubject(shape);
  516.     polyline.setAttributeNS(null,"points",path);
  517. }
  518.  
  519.  
  520.  
  521. /************************************************END ORTHO-LINE DRAW FUNCTIONS************************/
  522. /**
  523. *display all connection points, this will take the c:connection-point coordinates defined in 1000,1000 space 
  524. * and scale them to current coordinate system
  525. **/
  526. SVGRenderer.prototype.showConnectionPoints=function(shape){
  527.     if(!shape)return;
  528.     //debugger;
  529.     var rect=this.bounds(shape);
  530.     var rotation=rect['rotation'];
  531.     if(!rotation)rotation=0;
  532.     this.remove($('active-shape-tracker'));
  533.     var doc=this.container.ownerDocument;
  534.     var group=doc.createElementNS(this.svgNamespace,"g");
  535.     var svg=doc.createElementNS(this.svgNamespace,"svg");
  536.     group.appendChild(svg);
  537.     group.style.position="ABSOLUTE";
  538.     group.style.zIndex=this.maxIndex+1;
  539.     var centerX=parseInt(rect['x'])+parseInt(rect['width']/2);
  540.     var centerY=parseInt(rect['y'])+parseInt(rect['height']/2);
  541.     group.setAttributeNS(null,"transform","rotate("+rotation+","+centerX+","+centerY+")");
  542.     group.style.zIndex=(shape.style.zIndex*1)+1;
  543.     group.id='active-shape-tracker';
  544.     var width=rect['width'];
  545.     var height=rect['height'];
  546.     var nodeList=shape.getElementsByTagName("connection-point");
  547.     for(var i=0;i<nodeList.length;i++){
  548.         var node=nodeList.item(i);
  549.         var oval=doc.createElementNS(this.svgNamespace,"circle");
  550.         var x=parseInt(rect['x'])+(node.getAttribute('x')*width/this.COORD_X);
  551.         var y=parseInt(rect['y'])+(node.getAttribute('y')*height/this.COORD_Y);
  552.         oval.setAttributeNS(null,'fill',"red");
  553.         oval.setAttributeNS(null,'stroke',"black");
  554.         oval.style.position="ABSOLUTE";
  555.         oval.setAttributeNS(null,"cx",x);
  556.         oval.setAttributeNS(null,"cy",y);
  557.         oval.setAttributeNS(null,"r","3");
  558.         svg.appendChild(oval);
  559.     }
  560.     this.svgRoot.appendChild(group);
  561. }
  562.  
  563. /*
  564. *connectLine, first calculate if the line end matches a connection point
  565. * if yes then add an entry to ensure that line and shape are connected
  566. **/
  567. SVGRenderer.prototype.connectLine=function(shape,connector,toOrFrom){
  568.     
  569.     if(!connector)return;
  570.     //first disconnect the line
  571.     this.disconnectLineFromShape(connector,toOrFrom);
  572.     if(!shape)return;
  573.     //get the line coordinates in pixels
  574.     var screenxdpi=screen.logicalXDPI / 72;
  575.     var x=0;
  576.     var y=0;
  577.     var type=this.getConnectorType(connector);
  578.     if(type=='line'||type=='curve-line'){
  579.         var line=this.getShapeSubject(connector);
  580.     if(toOrFrom=="from"){
  581.         x=this.getConnectorFromX(connector);
  582.         y=this.getConnectorFromY(connector);
  583.      }
  584.      else{
  585.          x=this.getConnectorToX(connector);
  586.         y=this.getConnectorToY(connector);
  587.      }
  588.     }
  589.     else{
  590.         if(toOrFrom=="from"){
  591.             x=this.getShapeSubject(connector).points.getItem(0).x;
  592.             y=this.getShapeSubject(connector).points.getItem(0).y;
  593.         
  594.         }
  595.         else{
  596.             var length=this.getShapeSubject(connector).points.numberOfItems;
  597.             if(length==0)return;
  598.             x=this.getShapeSubject(connector).points.getItem(length-1).x;
  599.             y=this.getShapeSubject(connector).points.getItem(length-1).y;
  600.         }
  601.     
  602.     }
  603.     //now get the shape center
  604.     var rect=this.bounds(shape);
  605.     var centerX=parseInt(rect['x']*1)+parseInt(rect['width']/2);
  606.     var centerY=parseInt(rect['y']*1)+(rect['height']/2);
  607.     //get the rotation
  608.     var rotation=rect['rotation'];
  609.     if(!rotation)rotation=0;
  610.     //get the shape coordinate size, hardcode for now
  611.     
  612.     
  613.     var connectionList=shape.getElementsByTagName("connection-point");
  614.     for(var i=0;i<connectionList.length;i++){
  615.         var node=connectionList.item(i);
  616.         //for each connection point get its(unrotated) pixel location
  617.         var conX=(rect['x']*1)+((node.getAttributeNS(null,"x")/this.COORD_X)*rect['width']);
  618.         var conY=(rect['y']*1)+((node.getAttributeNS(null,"y")/this.COORD_Y)*rect['height']);
  619.         //now translate the center to the origin
  620.         conX=conX-centerX;
  621.         conY=conY-centerY;
  622.         //now rotate and translate back
  623.         var finalX=((conX*Math.cos((Math.PI/180)*(rotation)))-(conY*Math.sin((Math.PI/180)*(rotation)))*1)+(centerX*1);
  624.         var finalY=((conX*Math.sin((Math.PI/180)*(rotation)))+(conY*Math.cos((Math.PI/180)*(rotation)))*1)+(centerY*1);
  625.         
  626.         if(x>(finalX-4)&&x<((finalX*1)+4)&&y>(finalY-4)&&y<((finalY*1)+4)){
  627.             this.connectLineToShape(shape,connector,toOrFrom,node,i);
  628.             var isFrom=(toOrFrom=="from")?true:false;
  629.             this.moveLine(connector,finalX,finalY,isFrom);
  630.             $('help').innerHTML="Connected line to shape";
  631.             //no need to go on, we found our connection point
  632.             return;
  633.         }
  634.     
  635.     }
  636. }
  637.  
  638. /******************************END LINE FUNCTIONS********************************/
  639. /*******************************BEGIN SHAPE ATTRIBUTE GETTERS AND SETTERS************/
  640.  
  641. /**
  642. *return the type of this connector
  643. **/
  644. SVGRenderer.prototype.getConnectorType=function(shape){
  645.     return shape.getAttributeNS(null,"type");
  646.  
  647.  
  648. }
  649. /**
  650. *get from x for a valid connector
  651. **/
  652. SVGRenderer.prototype.getConnectorFromX=function(shape){
  653.     var x1=null;
  654.     var type=this.getConnectorType(shape);
  655.     if(type=='line'){
  656.         x1=this.getShapeSubject(shape).getAttributeNS(null,"x1");
  657.     }
  658.     else if(type=='curve-line'){
  659.         var subject=this.getShapeSubject(shape);
  660.         var path=subject.pathSegList;
  661.         x1=path.getItem(0).x;
  662.     }
  663.     else{
  664.         var polyline=this.getShapeSubject(shape);
  665.         var points=polyline.points;
  666.         if(points.numberOfItems>0)
  667.             x1=points.getItem(0).x;
  668.     }
  669.     return x1;
  670. }
  671. /**
  672. *get from y for a valid connector
  673. **/
  674. SVGRenderer.prototype.getConnectorFromY=function(shape){
  675.     var y1=null;
  676.     var type=this.getConnectorType(shape);
  677.     if(type=='line'){
  678.         y1=this.getShapeSubject(shape).getAttributeNS(null,"y1");
  679.         
  680.     }
  681.     else if(type=='curve-line'){
  682.         var subject=this.getShapeSubject(shape);
  683.         var path=subject.pathSegList;
  684.         y1=path.getItem(0).y;
  685.     }
  686.     else{
  687.         var polyline=this.getShapeSubject(shape);
  688.         var points=polyline.points;
  689.         if(points.numberOfItems>0)
  690.             y1=points.getItem(0).y;
  691.         
  692.     }
  693.     return y1;
  694. }
  695. /**
  696. *get to x for a valid connector
  697. **/
  698. SVGRenderer.prototype.getConnectorToX=function(shape){
  699.     var x2=null;
  700.     var type=this.getConnectorType(shape);
  701.     if(type=='line'){
  702.         x2=this.getShapeSubject(shape).getAttributeNS(null,"x2");        
  703.     }
  704.     else if(type=='curve-line'){
  705.         var subject=this.getShapeSubject(shape);
  706.         var path=subject.pathSegList;
  707.         x2=path.getItem(1).x;
  708.     }
  709.     else{
  710.         var polyline=this.getShapeSubject(shape);
  711.         var points=polyline.points;
  712.         var length=points.numberOfItems;
  713.         if(length==0)return null;
  714.         x2=points.getItem(length-1).x;
  715.         
  716.     }
  717.     return x2;
  718. }
  719. /**
  720. *get to y for a valid connector
  721. **/
  722.  
  723. SVGRenderer.prototype.getConnectorToY=function(shape){
  724.     var y2;
  725.     var type=this.getConnectorType(shape);
  726.     if(type=='line'){
  727.         y2=this.getShapeSubject(shape).getAttributeNS(null,"y2");
  728.     }
  729.     else if(type=='curve-line'){
  730.         var subject=this.getShapeSubject(shape);
  731.         var path=subject.pathSegList;
  732.         y2=path.getItem(1).y;
  733.     }
  734.     else{
  735.         var polyline=this.getShapeSubject(shape);
  736.         var points=polyline.points;
  737.         var length=points.numberOfItems;
  738.         if(length==0)return;
  739.         y2=points.getItem(length-1).y;
  740.     }
  741.     return y2;
  742. }
  743.  
  744. /**
  745. *get all shape objects (not including connectors)!
  746. **/
  747. SVGRenderer.prototype.getAllShapes=function(doc){
  748.     var nodes=doc.getElementsByTagName("g");
  749.     var array=new Array();
  750.     for (var i=0;i<nodes.length;i++){
  751.         if(!this.isConnector(nodes[i])){
  752.             array[array.length]=nodes[i];
  753.         }
  754.     }
  755.     return array;
  756. }
  757.  
  758. /**
  759. *get all connectors (but not shapes)
  760. **/
  761. SVGRenderer.prototype.getAllConnectors=function(doc){
  762.     var nodes=doc.getElementsByTagName("g");
  763.     var array=new Array();
  764.     for (var i=0;i<nodes.length;i++){
  765.         if(this.isConnector(nodes[i])){
  766.             array[array.length]=nodes[i];
  767.         }
  768.     }
  769.     return array;
  770. }
  771. /**
  772. *get the stroke width of the shape, 
  773. **/
  774. SVGRenderer.prototype.getStrokeWidth=function(shape){
  775.     if(!shape)return null;
  776.     return this.getShapeSubject(shape).getAttributeNS(null,"stroke-width");
  777.  
  778. }
  779.  
  780. /**
  781. *set the stroke width of the shape, 
  782. **/
  783. SVGRenderer.prototype.setStrokeWidth=function(shape,width){
  784.     this.getShapeSubject(shape).setAttributeNS(null,"stroke-width",width);
  785.     
  786. }
  787.  
  788. /**
  789. *get the line color
  790. **/
  791. SVGRenderer.prototype.getLineColor=function(shape){
  792.     return this.getShapeSubject(shape).getAttributeNS(null,"stroke");
  793.  
  794. }
  795.  
  796. /**
  797. *set the line color
  798. **/
  799. SVGRenderer.prototype.setLineColor=function(shape,value){
  800.    if(value=='')value='none';
  801.    this.getShapeSubject(shape).setAttributeNS(null, 'stroke', value);
  802.    if(this.isConnector(shape)){
  803.            var markers=this.getMarkers(shape);
  804.            markers[0].setAttributeNS(null,"stroke",value);
  805.            markers[0].setAttributeNS(null,"fill",value);
  806.            markers[1].setAttributeNS(null,"stroke",value);
  807.            markers[1].setAttributeNS(null,"fill",value);
  808.    
  809.    }
  810. }
  811.  
  812. /**
  813. *get the line color
  814. **/
  815. SVGRenderer.prototype.getOpacity=function(shape){
  816.     return this.getShapeSubject(shape).getAttributeNS(null,"fill-opacity");
  817.  
  818. }
  819.  
  820. /**
  821. *set the line color
  822. **/
  823. SVGRenderer.prototype.setOpacity=function(shape,value){
  824.     if (value != '')
  825.         this.getShapeSubject(shape).setAttributeNS(null, 'fill-opacity', value);
  826. }
  827.  
  828.  
  829. /**
  830. *get the fill color
  831. **/
  832. SVGRenderer.prototype.getFillColor=function(shape){
  833.     if(!this.isConnector(shape)){
  834.         if(!this.getLinearGradient(shape))
  835.             return this.getShapeSubject(shape).getAttributeNS(null,"fill");
  836.         else{
  837.             var gradient=this.getLinearGradientElement(shape);
  838.             var stop=gradient.getElementsByTagName("stop")[0];
  839.             return stop.getAttributeNS(null,"stop-color");
  840.         }
  841.     }
  842. }
  843.  
  844. /**
  845. *set the fill color
  846. **/
  847. SVGRenderer.prototype.setFillColor=function(shape,value){
  848.     if(this.isConnector(shape))return;
  849.     if(value=='') value='none';
  850.     var gradient=this.getLinearGradientElement(shape);
  851.     var stop=gradient.getElementsByTagName("stop")[0];
  852.     stop.setAttributeNS(null,'stop-color',value);
  853.     var isGradient=this.getLinearGradient(shape);
  854.     if(!isGradient)
  855.         this.getShapeSubject(shape).setAttributeNS(null, 'fill', value);
  856. }
  857.  
  858. /**
  859. * set the shadow for the shape even though it does not work in firefox 1.5, it should work in 2.0 and above
  860. **/
  861. SVGRenderer.prototype.setShadow=function(shape,value){
  862.     if (value != 'false')
  863.         this.getShapeSubject(shape).setAttributeNS(null, 'filter',"url(#shadow_filter)" );
  864.       else
  865.         this.getShapeSubject(shape).setAttributeNS(null, 'filter', '');
  866. }
  867.  
  868. SVGRenderer.prototype.getShadow=function(shape){
  869.     if(!shape)return false;
  870.     var value=this.getShapeSubject(shape).getAttributeNS(null,'filter');
  871.     return(value=="url(#shadow_filter)");
  872.     
  873.  
  874. }
  875.  
  876. /**
  877. *get the actual element that represents the linear gradient
  878. **/
  879.  
  880. SVGRenderer.prototype.getLinearGradientElement=function(shape){
  881.     var gradientList=shape.getElementsByTagName("linearGradient");
  882.     if(gradientList.length>0)return gradientList[0];
  883.     else return null;
  884. }
  885.  
  886. /**
  887. * set the linear gradient
  888. **/
  889. SVGRenderer.prototype.setLinearGradient=function(shape, value){
  890.     if(this.isConnector(shape))return;
  891.     var subject=this.getShapeSubject(shape);
  892.     var gradient=this.getLinearGradientElement(shape);
  893.     if(value){
  894.         var idURL="url(#"+gradient.id+")";
  895.         subject.setAttributeNS(null,"fill",idURL);
  896.     }
  897.     else{
  898.         var stop=gradient.getElementsByTagName("stop")[0];
  899.         var color=stop.getAttributeNS(null,"stop-color");
  900.         subject.setAttributeNS(null,"fill",color);
  901.     }
  902. }
  903. /**
  904. *return true or false indicating if the linear gradient is set
  905. **/
  906. SVGRenderer.prototype.getLinearGradient=function(shape){
  907.     var subject=this.getShapeSubject(shape);
  908.     var gradient=subject.getAttributeNS(null,"fill");
  909.     return(gradient.indexOf("url")>=0);
  910.  
  911.  
  912. }
  913.  
  914. /**
  915.  * this method is called during create or paste. The idea is to provide unique id's for all 
  916.  * linear gradients and match them to the corresponding paths
  917.  */
  918. SVGRenderer.prototype.fixLinearGradientID=function(shape){
  919.     //first get all the linear gradients
  920.     var gradients=shape.getElementsByTagName("linearGradient");
  921.     var subShapes=this.getAllSubShapes(shape);
  922.     for(var i=0;i<gradients.length;i++){
  923.         var gradient=gradients.item(i);
  924.         var gradientId=gradient.id;
  925.         var newGradientId="Gradient0"+(i+1)+createUUID();
  926.         gradient.id=newGradientId;
  927.         for(var j=0;j<subShapes.length;j++){
  928.             var subShape=subShapes.item(j);
  929.             if("url(#"+gradientId+")"==subShape.getAttributeNS(null,"fill")
  930.             ||"url("+gradientId+")"==subShape.getAttributeNS(null,"fill")){
  931.                 subShape.setAttributeNS(null,"fill","url(#"+newGradientId+")");
  932.             }
  933.         }
  934.         
  935.     }
  936. }
  937.  
  938. /**
  939. *return the marker elements
  940. **/
  941. SVGRenderer.prototype.getMarkers=function(shape){
  942.     return shape.getElementsByTagName("marker");
  943. }
  944.  
  945. /**
  946. *setLineStyle
  947. *@param shape
  948. *@param style: arrow-both, arrow-from, arrow-to, none
  949. **/
  950. SVGRenderer.prototype.setLineStyle=function(shape,style){
  951.     if(!this.isConnector(shape))return;
  952.     var markers=this.getMarkers(shape);
  953.     var idStart="";
  954.     var idEnd="";
  955.     if(style=='arrow-from'||style=='arrow-both'){
  956.         
  957.         idStart=markers[1].id;
  958.     }
  959.     
  960.     if(style=='arrow-to'||style=='arrow-both'){
  961.         
  962.         idEnd=markers[0].id
  963.     }
  964.     if(idStart.length>0){
  965.         idStart="url(#"+idStart+")";
  966.     }
  967.     if(idEnd.length>0){
  968.         idEnd="url(#"+idEnd+")";
  969.     }
  970.     var subject=this.getShapeSubject(shape);
  971.     subject.setAttributeNS(null,"marker-start",idStart);
  972.     subject.setAttributeNS(null,"marker-end",idEnd);
  973.  
  974.  
  975. }
  976. /**
  977. *getLineStyle
  978. **/
  979. SVGRenderer.prototype.getLineStyle=function(shape){
  980.     if(!this.isConnector(shape))return '';
  981.     var subject=this.getShapeSubject(shape);
  982.     var markerEnd=subject.getAttributeNS(null,"marker-end");
  983.     var markerStart=subject.getAttributeNS(null,"marker-start");
  984.     if(markerEnd.length>0&&markerStart.length>0)
  985.         return "arrow-both";
  986.     else if(markerEnd.length==0&&markerStart.length>0)
  987.         return "arrow-from";
  988.     else if(markerEnd.length>0&&markerStart.length==0)
  989.         return "arrow-to";
  990.     else
  991.         return "none";
  992.  
  993. }
  994. /**
  995.  * get the line dash style
  996.  * @return one of -"solid", "short-dash","long-dash"
  997.  */
  998.  SVGRenderer.prototype.getLineDashStyle=function(shape){
  999.      var subject=this.getShapeSubject(shape);
  1000.      var dashStyle=subject.getAttributeNS(null,"stroke-dasharray");
  1001.      if(!dashStyle||dashStyle=="")return "solid";
  1002.      else if(dashStyle==this.LONG_DASH)return "long-dash";
  1003.      else return "short-dash";
  1004.  }
  1005.  
  1006.  /**
  1007.   * set the line dash style, we will set this on all 
  1008.   */
  1009. SVGRenderer.prototype.setLineDashStyle=function(shape,style){
  1010.     if(style=="long-dash")style=this.LONG_DASH;
  1011.     else if(style=="short-dash")style=this.SHORT_DASH;
  1012.     else style="";
  1013.     if(this.isConnector(shape)){
  1014.         var subject=this.getShapeSubject(shape);
  1015.         subject.setAttributeNS(null,"stroke-dasharray",style)
  1016.     }
  1017.     else{
  1018.         var subShapes=this.getAllSubShapes(shape)
  1019.         for(var i=0;i<subShapes.length;i++){
  1020.             subShapes[i].setAttributeNS(null,"stroke-dasharray",style);
  1021.         }
  1022.     }
  1023. }
  1024. /**
  1025. *this method will return the actual subject of a shape, the subject could either be a path or line,polyline in case
  1026. of connectors, this assumes that the shape has only one subject
  1027. **/
  1028. SVGRenderer.prototype.getShapeSubject=function(shape){
  1029.     if(!shape)return null;
  1030.     if(this.isConnector(shape)){
  1031.         var type=this.getConnectorType(shape);
  1032.         if(type=='line')
  1033.             return shape.getElementsByTagName('line')[0];
  1034.         else if(type=='ortho-line')
  1035.             return shape.getElementsByTagName('polyline')[0];
  1036.         else if(type=='curve-line')
  1037.             return shape.getElementsByTagName('path')[0];
  1038.     }
  1039.     else if(shape.getElementsByTagName("path").length>0){
  1040.         return shape.getElementsByTagName("path")[0];
  1041.     }
  1042.     //otherwise its a primitive shape e.g rect
  1043.     else{
  1044.         return shape;
  1045.     }
  1046. }
  1047. /**
  1048.  * return all the subshapes for a given shape
  1049.  * @param shape
  1050.  * @return list of all subshapes
  1051.  */
  1052. SVGRenderer.prototype.getAllSubShapes=function(shape){
  1053.         if(!shape)return null;
  1054.         else return shape.getElementsByTagName("path");
  1055.     
  1056.     
  1057.     
  1058. };
  1059. /**
  1060. *get x:
  1061. **/
  1062. SVGRenderer.prototype.setX=function(shape,x){
  1063.     if(shape){
  1064.         var svg=shape.getElementsByTagName("svg")[0];
  1065.         if(svg){
  1066.             svg.setAttributeNS(null, 'x',x+'px');
  1067.         }
  1068.     }
  1069.  
  1070. }
  1071. /**
  1072. * get the x value
  1073. **/
  1074. SVGRenderer.prototype.getX=function(shape,x){
  1075.     if(shape){
  1076.         var svg=shape.getElementsByTagName("svg")[0];
  1077.         if(svg){
  1078.             var x=svg.getAttribute("x");
  1079.             return x.split('px')[0];
  1080.         }
  1081.     }
  1082.  
  1083. }
  1084.  
  1085. SVGRenderer.prototype.getY=function(shape,x){
  1086.     if(shape){
  1087.         var svg=shape.getElementsByTagName("svg")[0];
  1088.         if(svg){
  1089.             var y=svg.getAttribute("y");
  1090.             return y.split('px')[0];
  1091.             
  1092.         }
  1093.     }
  1094.  
  1095. }
  1096. SVGRenderer.prototype.setY=function(shape,y){
  1097.     if(shape){
  1098.         var svg=shape.getElementsByTagName("svg")[0];
  1099.         if(svg){
  1100.             svg.setAttributeNS(null, 'y',y+'px');
  1101.         }
  1102.     }
  1103.  
  1104. }
  1105.  
  1106. /**
  1107. *set the width, we take the template path and take every x element and multiply it with
  1108. *the corresponding template.x/this.COORD_X
  1109. **/
  1110. SVGRenderer.prototype.setWidth=function(shape,width){
  1111.      if(shape){
  1112.         //first set the width in the svg element
  1113.         shape.getElementsByTagName("svg")[0].setAttributeNS(null,"width",width);
  1114.         //take tuples of paths and set width on them
  1115.         var paths=shape.getElementsByTagName("path");
  1116.         for (var i=0;i<(paths.length/2);i++){
  1117.             var index=i*2;
  1118.             this.setPathWidth(paths[index],paths[(index*1)+1],width);
  1119.         }
  1120.     }    
  1121. }
  1122. /**
  1123.  *  private method to set the path width
  1124.  * 
  1125.  */
  1126.  SVGRenderer.prototype.setPathWidth=function(path,template,width){
  1127.         var pathSegList=path.pathSegList;
  1128.         var tempSegList=template.pathSegList;
  1129.         //these should match
  1130.         for(var i=0;i<pathSegList.numberOfItems;i++){
  1131.             var pathItem=pathSegList.getItem(i);
  1132.             var pathType=pathItem.pathSegTypeAsLetter;
  1133.             var tempItem=tempSegList.getItem(i);
  1134.             pathItem.x=(width)*(tempItem.x/this.COORD_X);
  1135.             if(pathType=='M'||pathType=='L')continue;
  1136.             if(pathType=='A'){
  1137.                 pathItem.r1=(width)*(tempItem.r1/this.COORD_X);
  1138.                 continue;
  1139.             }
  1140.             if(pathType=='C'){
  1141.                 pathItem.x1=(width)*(tempItem.x1/this.COORD_X);
  1142.                 pathItem.x2=(width)*(tempItem.x2/this.COORD_X);
  1143.                 continue;
  1144.             }
  1145.             
  1146.         }
  1147.         
  1148.     }
  1149.  
  1150. /**
  1151. **set the height, we take the template path and take every x element and multiply it with
  1152. *the corresponding template.x/this.COORD_X
  1153. **/
  1154. SVGRenderer.prototype.getWidth=function(shape,width){
  1155.     if(shape){
  1156.         return shape.getElementsByTagName("svg")[0].getAttributeNS(null,"width");
  1157.         }
  1158. }
  1159. /**
  1160. *set the height, not sure if this is the correct way to access the matrix elements
  1161. **/
  1162. SVGRenderer.prototype.setHeight=function(shape,height){
  1163.     if(shape){
  1164.         //first set the width in the svg element
  1165.         shape.getElementsByTagName("svg")[0].setAttributeNS(null,"height",height);
  1166.         var paths=shape.getElementsByTagName("path");
  1167.         for (var i=0;i<(paths.length/2);i++){
  1168.             var index=i*2;
  1169.             this.setPathHeight(paths[index],paths[(index*1)+1],height);
  1170.         }
  1171.     }    
  1172. }
  1173. /**
  1174.  * private method to set path height
  1175.  */
  1176. SVGRenderer.prototype.setPathHeight=function(path,template,height){
  1177.         var pathSegList=path.pathSegList;
  1178.         var tempSegList=template.pathSegList;
  1179.         //these should match
  1180.         for(var i=0;i<pathSegList.numberOfItems;i++){
  1181.             var pathItem=pathSegList.getItem(i);
  1182.             var tempItem=tempSegList.getItem(i);
  1183.             var pathType=pathItem.pathSegTypeAsLetter;
  1184.             pathItem.y=(height)*(tempItem.y/this.COORD_Y);
  1185.             if(pathType=='M'||pathType=='L')continue;
  1186.             if(pathType=='A'){
  1187.                 pathItem.r2=(height)*(tempItem.r2/this.COORD_Y);
  1188.                 continue;
  1189.             }
  1190.             if(pathType=='C'){
  1191.                 pathItem.y1=(height)*(tempItem.y1/this.COORD_Y);
  1192.                 pathItem.y2=(height)*(tempItem.y2/this.COORD_Y);
  1193.                 continue;
  1194.             }
  1195.         }
  1196. }
  1197.     
  1198.  
  1199.  
  1200. /**
  1201. *get the height, not sure if this is the correct way to access the matrix elements
  1202. **/
  1203. SVGRenderer.prototype.getHeight=function(shape,height){
  1204.     if(shape){
  1205.         return shape.getElementsByTagName("svg")[0].getAttributeNS(null,"height");
  1206.         }
  1207. }
  1208.  
  1209. /**
  1210. * get the rotation, the rotation is available set at the  shape level itelf (g)
  1211. **/
  1212. SVGRenderer.prototype.getRotation=function(shape){
  1213.     if(!shape)return null;
  1214.     var item=shape.transform.baseVal.getItem(0);
  1215.     return item.angle;
  1216.  
  1217. }
  1218. /**
  1219. *get the center x point of the shape
  1220. **/
  1221. SVGRenderer.prototype.getCenterX=function(shape){
  1222.     var box=this.bounds(shape);
  1223.     return (box.x*1)+((box.width*1)/2);
  1224.  
  1225. }
  1226. /**
  1227. *get the center y point of the shape
  1228. **/
  1229. SVGRenderer.prototype.getCenterY=function(shape){
  1230.     var box=this.bounds(shape);
  1231.     return (box.y*1)+((box.height*1)/2);
  1232. }
  1233. /**
  1234. * set the rotation to be the center of the shape
  1235. **/
  1236. SVGRenderer.prototype.setRotation=function(shape,angle){
  1237.     if(!shape)return null;
  1238.     var box=this.bounds(shape);
  1239.     var centerX=(box.x*1)+((box.width/2)*1);
  1240.     var centerY=(box.y*1)+((box.height/2)*1);
  1241.     var translate="rotate("+angle+","+ centerX+","+centerY+")";
  1242.     shape.setAttributeNS(null,'transform',translate);
  1243.     var item=shape.transform.baseVal.getItem(0);
  1244.     item.matrix.rotate(angle);
  1245. }
  1246.  
  1247. /** 
  1248. *a utility function to update rotation of the shape after a reset in x,y,width or height
  1249. **/
  1250. SVGRenderer.prototype.updateRotation=function(shape){
  1251.         var angle=this.getRotation(shape);
  1252.            this.setRotation(shape,angle);
  1253.  
  1254. }
  1255. /**
  1256. *set the shape cursor
  1257. **/
  1258. SVGRenderer.prototype.setCursor=function(shape,cursor){
  1259.     if(cursor=='move'||cursor=='resize'||cursor=='crosshair')
  1260.     shape.style.cursor=cursor;
  1261.     else
  1262.     shape.style.cursor="URL("+cursor+"),auto";
  1263.     
  1264.  
  1265. }
  1266. /************************************END SHAPE ATTRIBUTE GETTERS AND SETTERS********************/
  1267. /****************************BEGIN SHAPE MANIPULATION FUNCTIONS(MOVE,RESIZE,ROTATE)************/
  1268. /**
  1269. *rotate method called from editor
  1270. **/
  1271. SVGRenderer.prototype.rotate=function(shape,rotation){
  1272.     if(!rotation){
  1273.         rotation=0;
  1274.     }
  1275.     rotation=rotation%360;
  1276.     if(rotation<0){
  1277.         rotation=360+rotation;
  1278.     }
  1279.     this.setRotation(shape,rotation);
  1280.  
  1281. }
  1282. /**
  1283. *respond to move keys
  1284. **/
  1285. SVGRenderer.prototype.fineMove = function(shape, move, isHorizontal) {
  1286.   //todo fix for line!!!
  1287.   if(!shape||this.isConnector(shape))return;
  1288.   
  1289.   
  1290.     if(isHorizontal){
  1291.         var left=this.getX(shape);
  1292.         left=(left*1)+move;
  1293.         this.setX(shape,left);
  1294.     
  1295.     }
  1296.     else{
  1297.         var top=this.getY(shape);
  1298.         top=(top*1)+move;
  1299.         this.setY(shape,top);
  1300.     }
  1301.     this.updateRotation(shape);
  1302.   
  1303. };
  1304. /**
  1305. *respond to shift+R and shift+L
  1306. **/
  1307. SVGRenderer.prototype.fineRotateSelection=function(shape,angle){
  1308.     if(this.isConnector(shape))return;
  1309.     var rotation=this.getRotation(shape);
  1310.         if(!rotation)
  1311.             rotation=0;
  1312.     var rotation=rotation+angle;
  1313.     rotation=rotation%360;
  1314.     if(rotation<0){
  1315.         rotation=360+rotation;
  1316.         
  1317.     }
  1318.     this.setRotation(shape,rotation);
  1319.     
  1320. };
  1321. SVGRenderer.prototype.remove = function(shape) {
  1322.   if(shape)
  1323.       shape.parentNode.removeChild(shape);
  1324. }
  1325.  
  1326.  
  1327. /**
  1328. * move the shape based on mouse movement
  1329. **/
  1330. SVGRenderer.prototype.move = function(shape, left, top) {
  1331.    this.setX(shape,left);
  1332.    this.setY(shape,top);
  1333.    this.updateRotation(shape);
  1334.   
  1335. };
  1336.  
  1337.  
  1338. /**
  1339. *resize height:
  1340. **/
  1341.  
  1342.  
  1343.  
  1344. /**
  1345. *this resize is called during draw, 
  1346. *after the draw is complete, subsequent resizes are handled by resizewidth or resizeheight
  1347. **/
  1348. SVGRenderer.prototype.resize = function(shape, fromX, fromY, toX, toY) {
  1349.   var deltaX = toX - fromX;
  1350.   var deltaY = toY - fromY;
  1351.  
  1352.   if (this.isConnector(shape)) {
  1353.         var type=this.getConnectorType(shape);
  1354.           if(type=='line'){
  1355.                this.setLineTo(shape,toX,toY);
  1356.                return;
  1357.            }
  1358.            else if (type=='ortho-line'){
  1359.                this.drawOrthoLine(shape,fromX,fromY,toX,toY);
  1360.                return;
  1361.            }
  1362.            else if (type=='curve-line'){
  1363.             this.drawCurveLine(shape,fromX,fromY,toX,toY,false);
  1364.             return;
  1365.         }
  1366.            
  1367.   }
  1368.    
  1369.    if (deltaX < 0) {
  1370.       this.setX(shape,toX);
  1371.       this.setWidth(shape,-deltaX );
  1372.       
  1373.     }
  1374.     else {
  1375.       this.setWidth(shape,deltaX);
  1376.       
  1377.     }
  1378.   
  1379.     if (deltaY < 0) {
  1380.       this.setY(shape,toY);
  1381.       this.setHeight(shape,-deltaY );
  1382.      
  1383.     }
  1384.     else {
  1385.       this.setHeight(shape,deltaY);
  1386.      
  1387.     }
  1388.       this.updateRotation(shape);
  1389. };
  1390.  
  1391. /*******************************************BEGIN CURVE CONNECTOR FUNCTIONS***********************************/
  1392. SVGRenderer.prototype.drawCurveLine=function(shape,fromX,fromY,toX,toY,resize){
  1393.     var subject=this.getShapeSubject(shape);
  1394.     this.setLineFrom(shape,fromX,fromY);
  1395.     this.setLineTo(shape,toX,toY);
  1396.     if(!resize){
  1397.         var x1=Math.abs(fromX-toX);
  1398.         var y1=Math.abs(fromY-toY);
  1399.         var cx1=(fromX<toX)?(fromX*1)+(x1*(1/4)):(fromX*1)-(x1*(1/4));
  1400.         var cx2=(fromX<toX)?(toX*1)-(x1*(1/4)):(toX*1)+(x1*(1/4));
  1401.         var cy1=(fromY<toY)?(fromY*1)+(y1*(1/4)):(fromY*1)-(y1*(1/4));
  1402.         var cy2=(fromY<toY)?(toY*1)-(y1*(1/4)):(toY*1)+(y1*(1/4));
  1403.         this.setControl1(shape,cx1,cy1);
  1404.         this.setControl2(shape,cx2,cy2);
  1405.         
  1406.         
  1407.     }
  1408. }
  1409. /********************************************END CURVE CONNECTOR FUNCTIONS*************************************/
  1410.  
  1411.  
  1412. /****************************END SHAPE MANIPULATION FUNCTIONS(MOVE,RESIZE,ROTATE)************/
  1413. /**
  1414. *command handler for this renderer
  1415. **/
  1416. SVGRenderer.prototype.editCommand = function(shape, cmd, value,zoom)
  1417. {
  1418.   if (shape != null) {
  1419.       if(cmd=='sendBack'){
  1420.         this.sendToBack(shape);
  1421.     }
  1422.     else if(cmd=='bringFront'){
  1423.         this.bringToFront(shape);
  1424.     }
  1425.     else if (cmd == 'fillcolor') {
  1426.       this.setFillColor(shape,value);
  1427.     }
  1428.     else if (cmd == 'linecolor') {
  1429.       this.setLineColor(shape,value);
  1430.     }
  1431.     else if (cmd == 'linewidth') {
  1432.       this.setStrokeWidth(shape, parseInt(value) );
  1433.     }
  1434.      else if(cmd=='opacity'){
  1435.         this.setOpacity(shape,value);
  1436.     }
  1437.     else if(cmd=='shadow'){
  1438.         this.setShadow(shape,value);
  1439.     }
  1440.     else if(cmd=='gradient'){
  1441.         value=(value=='solid')?false:true;
  1442.         this.setLinearGradient(shape,value);
  1443.     }
  1444.     else if(cmd=='linestyle'){
  1445.         this.setLineStyle(shape,value);
  1446.     }
  1447.     else if (cmd=='linedashstyle'){
  1448.         this.setLineDashStyle(shape,value);
  1449.     }
  1450.     else if(cmd=='fontSize'||cmd=='fontFamily'||cmd=='bold'||cmd=='italic'||cmd=='fontColor'||cmd=='align'){
  1451.         
  1452.         var font=new Object();
  1453.         font.size='';
  1454.         font.family='';
  1455.         font.color='';
  1456.         font.align='';
  1457.         font.italics='';
  1458.         font.bold='';
  1459.         if(cmd=='fontSize'){
  1460.             font.size=value;
  1461.             this.setFont(shape,font,zoom);
  1462.         }
  1463.         else if(cmd=='fontFamily'){
  1464.             font.family=value;
  1465.             this.setFont(shape,font,zoom);
  1466.         }
  1467.         else if(cmd=='bold'){
  1468.             var oldFont=this.getFont(shape);
  1469.             
  1470.             if(oldFont.bold=='bold'){
  1471.                 font.bold='normal';
  1472.             }
  1473.             else{
  1474.                 font.bold='bold';
  1475.             }
  1476.             this.setFont(shape,font);
  1477.         }
  1478.    
  1479.         else if(cmd=='italic'){
  1480.             //debugger;
  1481.             var oldFont=this.getFont(shape);
  1482.             if(oldFont.italics=='italic'){
  1483.                 font.italics='normal';
  1484.             }
  1485.             else{
  1486.                 font.italics='italic';
  1487.             }
  1488.             this.setFont(shape,font);
  1489.         }
  1490.         else if(cmd=='fontColor'){
  1491.             font.color=value;
  1492.             this.setFont(shape,font);
  1493.         }
  1494.         else if(cmd=='align'){
  1495.             font.align=value;
  1496.             this.setFont(shape,font);
  1497.         }
  1498.     
  1499.     }
  1500.   }
  1501. }
  1502.  
  1503. /**
  1504. *query handler for this renderer
  1505. **/
  1506. SVGRenderer.prototype.queryCommand = function(shape, cmd)
  1507. {
  1508.   var result = '';
  1509.   
  1510.   if (shape != null) {
  1511.     if (cmd == 'fillcolor') {
  1512.       return this.getFillColor(shape);
  1513.     }
  1514.     else if (cmd == 'linecolor') {
  1515.       return this.getLineColor(shape);
  1516.     }
  1517.     else if (cmd == 'linewidth') {
  1518.       var width= this.getStrokeWidth(shape);
  1519.       if(width&&!width.indexOf('px')>=0)
  1520.           width=width+'px';
  1521.       return width;
  1522.     }
  1523.   
  1524.      else if(cmd=='font'){
  1525.         
  1526.         return this.getFont(shape);
  1527.     }
  1528.     else if(cmd=='linestyle'){
  1529.         return this.getLineStyle(shape);
  1530.     }
  1531.     else if (cmd=='linedashstyle'){
  1532.         return this.getLineDashStyle(shape);
  1533.     }
  1534.     else if(cmd=='opacity'){
  1535.         return this.getOpacity(shape);
  1536.     }
  1537.     else if(cmd=="gradient"){
  1538.         if(this.getLinearGradient(shape))return 'gradient';
  1539.         else return 'solid';
  1540.     }
  1541.     else if(cmd=="shadow"){
  1542.         return ""+this.getShadow(shape);
  1543.     }
  1544.     
  1545.   }
  1546.   return result;
  1547. }
  1548.  
  1549.  
  1550. /*********************************************TRACKER FUNCTIONS***************************************/
  1551. /**
  1552. *show the line tracker
  1553. **/
  1554. SVGRenderer.prototype.showLineTracker=function(shape){
  1555.     var parent=this.loadShape("tracker","g");
  1556.     this.svgRoot.appendChild(parent);
  1557.     parent.setAttributeNS(null,"id","tracker-group");
  1558.     this.updateLineTracker(shape,parent);
  1559.     
  1560.     return parent;
  1561. }
  1562.  
  1563. SVGRenderer.prototype.updateLineTracker=function(shape,parent){
  1564.     var oval=parent.getElementsByTagName("circle")[0];
  1565.     var type=this.getConnectorType(shape);
  1566.     if(type=='line'||type=='curve-line'){
  1567.         var x1=this.getConnectorFromX(shape);
  1568.         var y1=this.getConnectorFromY(shape);
  1569.         oval.setAttributeNS(null,"cx",x1);
  1570.         oval.setAttributeNS(null,"cy",y1);
  1571.         if(type=='curve-line'){
  1572.             var line=parent.getElementsByTagName("line")[0];
  1573.             line.setAttributeNS(null,'x1',x1);
  1574.             line.setAttributeNS(null,'y1',y1);
  1575.         }
  1576.     }
  1577.     else if (type=='ortho-line'){
  1578.         var polyline=this.getShapeSubject(shape);
  1579.         var points=polyline.points;
  1580.         var x1=points.getItem(0).x;
  1581.         var y1=points.getItem(0).y;
  1582.         oval.setAttributeNS(null,"cx",x1);
  1583.         oval.setAttributeNS(null,"cy",y1);
  1584.     }
  1585.     oval.style.zIndex=this.maxIndex+1;
  1586.     oval=parent.getElementsByTagName("circle")[1];
  1587.     if(type=='line'||type=='curve-line'){
  1588.         var x2=this.getConnectorToX(shape);
  1589.         var y2=this.getConnectorToY(shape);;
  1590.         oval.setAttributeNS(null,"cx",x2);
  1591.         oval.setAttributeNS(null,"cy",y2);
  1592.         if(type=='curve-line'){
  1593.             var line=parent.getElementsByTagName("line")[1];
  1594.             line.setAttributeNS(null,'x1',x2);
  1595.             line.setAttributeNS(null,'y1',y2);
  1596.         }
  1597.         
  1598.     }
  1599.     else if (type=='ortho-line'){
  1600.         var polyline=this.getShapeSubject(shape);
  1601.         var points=polyline.points;
  1602.         var length=points.numberOfItems;
  1603.         if(length==0)return;
  1604.         var x2=points.getItem(length-1).x;
  1605.         var y2=points.getItem(length-1).y;
  1606.         oval.setAttributeNS(null,"cx",x2);
  1607.         oval.setAttributeNS(null,"cy",y2);
  1608.     }
  1609.     if(type=='curve-line'){
  1610.         var control1=this.getControl1(shape);
  1611.         oval=parent.getElementsByTagName("circle")[2];
  1612.         oval.setAttributeNS(null,"cx",control1.x);
  1613.         oval.setAttributeNS(null,"cy",control1.y);
  1614.         oval.style.visibility="visible";
  1615.         var line=parent.getElementsByTagName("line")[0];
  1616.         line.setAttributeNS(null,'x2',control1.x);
  1617.         line.setAttributeNS(null,'y2',control1.y);
  1618.         
  1619.         var control2=this.getControl2(shape);
  1620.         oval=parent.getElementsByTagName("circle")[3];
  1621.         oval.setAttributeNS(null,"cx",control2.x);
  1622.         oval.setAttributeNS(null,"cy",control2.y);
  1623.         oval.style.visibility="visible";
  1624.         line=parent.getElementsByTagName("line")[1];
  1625.         line.setAttributeNS(null,'x2',control2.x);
  1626.         line.setAttributeNS(null,'y2',control2.y);
  1627.     }
  1628.     
  1629.     oval.style.zIndex=this.maxIndex+1;
  1630.     //now set the tracker
  1631. }
  1632. /**
  1633. *load the tracker and show it, we may want to cache the tracker if it becomes a performance issue
  1634. **/
  1635. SVGRenderer.prototype.showTracker = function(shape) {
  1636.   if(!shape)return
  1637.   var tracker = $('tracker-group');
  1638.   if (tracker) {
  1639.     this.remove(tracker);
  1640.   }
  1641.   if(this.isConnector(shape))
  1642.   {
  1643.       return this.showLineTracker(shape);
  1644.   }
  1645.   
  1646.   tracker=this.loadShape("tracker-group","g");
  1647.   
  1648.   this.svgRoot.appendChild(tracker);
  1649.   this.updateTracker(shape);
  1650.   return tracker;
  1651. }
  1652. /**
  1653. *update the tracker if its already present
  1654. **/
  1655. SVGRenderer.prototype.updateTracker=function(shape){
  1656.     if(!shape)return;
  1657.     var tracker=$('tracker-group');
  1658.     if(tracker){
  1659.         if(this.isConnector(shape))
  1660.             return this.updateLineTracker(shape,tracker);
  1661.     }
  1662.     if(!$('tracker-group'))return this.showTracker(shape);
  1663.     
  1664.     var box=this.bounds(shape);
  1665.     var trackerGroup=$('tracker-group');
  1666.     var tracker=$('tracker');
  1667.     var width=(parseInt(box.width)+10);
  1668.     var height=(parseInt(box.height)+10);
  1669.     var x=(parseInt(box.x)-5);
  1670.     var y=(parseInt(box.y)-5);
  1671.     var centerX=(x*1)+(width/2);
  1672.     var centerY=(y*1)+(height/2);
  1673.     var translate="rotate("+box.rotation+","+ centerX+","+centerY+")";
  1674.     trackerGroup.setAttributeNS(null,'transform',translate);
  1675.     tracker.setAttributeNS(null,'width',width+'px');
  1676.     tracker.setAttributeNS(null,'height',height+'px');
  1677.     tracker.parentNode.setAttributeNS(null,'x',x+'px');
  1678.     tracker.parentNode.setAttributeNS(null,'y',y+'px');
  1679.     $('resize-left').setAttributeNS(null,'y',(box.height/2)+'px');
  1680.     $('resize-top').setAttributeNS(null,'x',(box.width/2)+'px');
  1681.     var resizeBottom=$('resize-bottom');
  1682.     resizeBottom.setAttributeNS(null,'x',(box.width/2)+'px');
  1683.     resizeBottom.setAttributeNS(null,'y',(parseInt(box.height)+5)+'px');
  1684.     var resizeRight=$('resize-right');
  1685.     resizeRight.setAttributeNS(null,'x',(parseInt(box.width)+5)+'px');
  1686.     resizeRight.setAttributeNS(null,'y',(box.height/2)+'px');
  1687.     $('tracker-rotate').setAttributeNS(null,'cx',((box.width/2)+5)+'px');
  1688.     //set the rotation
  1689.     
  1690.     
  1691.     
  1692.     
  1693. }
  1694. /**************************************END TRACKER FUNCTIONS*****************************************/
  1695. /***************************************BEGIN TEXT FUNCTIONS****************************************/
  1696. /**
  1697. *note:some text functions are inherited from abstractRenderer (see vmlrenderer.js)
  1698. **/
  1699. /**
  1700. *this method should be called only after getShapeText has been called by the editor to save the text
  1701. */
  1702. SVGRenderer.prototype.clearShapeText=function(shape){
  1703.     var nodes=shape.getElementsByTagName("text");
  1704.     var nodeArray=$A(nodes);
  1705.     for(var i=0;i<nodeArray.length;i++){
  1706.         var node=nodeArray[i];
  1707.         if(node.id=="text:normal"||node.id=="text:newline")
  1708.             this.remove(node);
  1709.     }
  1710.     if(this.isConnector(shape)){
  1711.         var bgShape=shape.getElementsByTagName("rect");
  1712.         if(bgShape.length>0){
  1713.             this.hideConnectorBackground(bgShape[0]);
  1714.         }
  1715.     }
  1716. }
  1717.  
  1718.  
  1719. /**
  1720.  * basically call to handleTextLinePositioning for svg, since text is handled in the same manner for connectors and shapes,
  1721.  * the vml versio is implemented
  1722.  * @see vmlrenderer.js#handleConnectorTextLinePositioning
  1723.  */
  1724. SVGRenderer.prototype.handleConnectorTextLinePositioning=function(height,width,x,y,center,fontSize,lines,shapeFont,shape){
  1725.     
  1726.     return this.handleTextLinePositioning(height,width,x,y,center,fontSize,lines,shapeFont,shape);
  1727.     
  1728. }
  1729. /**
  1730. *create the text elements and handle text positioning
  1731. **/
  1732. SVGRenderer.prototype.handleTextLinePositioning=function(height,width,x,y,center,fontSize,lines,shapeFont,shape){
  1733.     var centerY=(y*1)+(height*1)/2;
  1734.     var align;
  1735.     if(shapeFont.align=='center'){
  1736.         align=(x*1)+(width/2);
  1737.     }
  1738.     else if(shapeFont.align=='left'){
  1739.         align=(x*1)+(10*1)
  1740.     }
  1741.     else{
  1742.         align=(x*1)+(width-10);
  1743.     }
  1744.     
  1745.     var shapeArray=new Array();
  1746.     for (var i=center;i>0;i--){
  1747.         var lineTopMargin=(centerY)+((fontSize*1.1)*(i-center));
  1748.         lineTopMargin=(lineTopMargin*1)+((fontSize)/4);
  1749.         shapeArray[shapeArray.length]=this.createTextShape(lines[i-1],true,lineTopMargin,null,align,null,shapeFont,shape);
  1750.     }
  1751.     for (var i=center;i<lines.length;i++){
  1752.         var lineTopMargin=(centerY)+((fontSize*1.1)*(i+1-center));
  1753.         lineTopMargin=(lineTopMargin*1)+((fontSize)/4);
  1754.         shapeArray[shapeArray.length]=this.createTextShape(lines[i],true,lineTopMargin,null,align,null,shapeFont,shape);
  1755.     }
  1756.     return shapeArray;
  1757.     
  1758. }
  1759. /**
  1760.  * set the dimensions of the background shape for the connector text
  1761.  * todo, fix visibility here...
  1762.  */
  1763. SVGRenderer.prototype.handleConnectorTextBackgroundPositioning=function(shape,rect,text){
  1764.     var bgShape=this.getConnectorBackgroundShape(shape);
  1765.     shape.getElementsByTagName("svg")[0].appendChild(bgShape);
  1766.     if(text&&trim(text).length>0){
  1767.         bgShape.setAttributeNS(null,"fill","white");
  1768.         bgShape.setAttributeNS(null,"x",rect.x);
  1769.         bgShape.setAttributeNS(null,"y",rect.y);
  1770.         bgShape.setAttributeNS(null,"width",rect.width);
  1771.         bgShape.setAttributeNS(null,"height",rect.height);
  1772.     }
  1773.     else{
  1774.         
  1775.         this.hideConnectorBackground(bgShape);
  1776.     }
  1777.     
  1778. }
  1779. /**
  1780.  * hide the connector background, this comes handy when we want to clear the connector text (during moves, resize etc)
  1781.  * or when the text is empty
  1782.  * @param background shape for the connector
  1783.  */
  1784. SVGRenderer.prototype.hideConnectorBackground=function(bgShape){
  1785.     if(bgShape){
  1786.         bgShape.setAttributeNS(null,"x",0);
  1787.         bgShape.setAttributeNS(null,"y",0);
  1788.         bgShape.setAttributeNS(null,"width",0);
  1789.         bgShape.setAttributeNS(null,"height",0);
  1790.     }
  1791. }
  1792. /**
  1793. * a utility function to create a text set, sometimes we may need to create a dummy text set (which can hold the
  1794. *default values for font etc. (see setShapeText)in which case
  1795. * we need to pass the shape.id as the type in the line object and texpathok=false
  1796. */
  1797. SVGRenderer.prototype.createTextShape=function(line,textpathok,lineTopMargin,lineHeightMargin,start,end,shapeFont,containerShape){
  1798.     var shape=null;
  1799.     
  1800.     if(!textpathok){
  1801.             shape=containerShape.ownerDocument.getElementById("text:template"+line.type);
  1802.         
  1803.     }
  1804.     if(textpathok||!shape){
  1805.     
  1806.         shape=this.createElement("text",this.svgNamespace);
  1807.         if(textpathok)
  1808.             shape.id="text:"+line.type;
  1809.         else
  1810.             shape.id="text:template"+line.type;
  1811.     }
  1812.     shape.setAttributeNS(null,"x",start);
  1813.     shape.setAttributeNS(null,"y",lineTopMargin);
  1814.     shape.style.position="absolute";
  1815.     shape.setAttributeNS(null,"fill",shapeFont.color);
  1816.     shape.setAttributeNS(null,"font-size",shapeFont.size);
  1817.     shape.setAttributeNS(null,"font-weight",shapeFont.bold);
  1818.     shape.setAttributeNS(null,"font-family",shapeFont.family);
  1819.     shape.setAttributeNS(null,"font-style",shapeFont.italics);
  1820.     //directive to preserve any space
  1821.     shape.setAttribute("xml:space","preserve");
  1822.     var textAnchor="middle";
  1823.     if(shapeFont.align=='left'){
  1824.         textAnchor="start";
  1825.     }
  1826.     else if(shapeFont.align=='right'){
  1827.         textAnchor="end";
  1828.     }
  1829.     shape.setAttributeNS(null,"text-anchor",textAnchor);
  1830.     shape.textContent=line.text;
  1831.     return shape;
  1832.  
  1833. }
  1834.  
  1835. /**
  1836. *utility function to set the fontsize,fontcolor,fontfamily,fontdecoration(bold,italics,underline) and textalign for a given shape
  1837. * if you want to selectively set something e.g size, then only pass size in the font leaving the rest of the stuff as null
  1838. */
  1839. SVGRenderer.prototype.setFont=function(shape,font,zoom){
  1840.     
  1841.     var dummyText=this.getShapeText(shape);
  1842.     //if this is null, then dummy text does not exist
  1843.     //so we have to create one and then we leave
  1844.     if(!dummyText){
  1845.         this.fillUpFont(font);
  1846.         this.setShapeText(shape," ",font,true,null,zoom);
  1847.         return;
  1848.     }
  1849.     //we already have text...now we can start, get the text shapes first
  1850.     var textList=shape.getElementsByTagName("text");
  1851.     var shapeFont=this.getFont(shape);
  1852.     //if font size changes, we really need to redo the spacing etc.
  1853.     if(font.size!=''&&(font.size!=shapeFont.size)){
  1854.         
  1855.         this.clearShapeText(shape);
  1856.         this.setShapeText(shape,dummyText,font,true,shapeFont,zoom);
  1857.         
  1858.     }
  1859.     //otherwise we will set things individually, no need to create things 
  1860.     if(font.color!=''){
  1861.         for(var i=0;i<textList.length;i++){
  1862.             textList[i].setAttributeNS(null,"fill",font.color);
  1863.             
  1864.         }
  1865.     }    
  1866.     //now set the text path specific properties
  1867.     if(font.family!=''){
  1868.     for(var i=0;i<textList.length;i++){
  1869.             textList[i].setAttributeNS(null,"font-family",font.family);
  1870.         }
  1871.     }
  1872.     if(font.bold!=''){
  1873.         for(var i=0;i<textList.length;i++){
  1874.             textList[i].setAttributeNS(null,"font-weight",font.bold);
  1875.         }
  1876.     }
  1877.     if(font.italics!=''){
  1878.         for(var i=0;i<textList.length;i++){
  1879.             textList[i].setAttributeNS(null,"font-style",font.italics);
  1880.         }
  1881.     }
  1882.     if(font.align!=''){
  1883.         var align;
  1884.         //pass dummytext and zoom for connectors
  1885.         var rect=this.getTextBounds(shape,dummyText,zoom);
  1886.         var x=rect['x'];
  1887.         var width=rect['width'];
  1888.         if(font.align=='center'){
  1889.             align=(x*1)+(width/2);
  1890.         }
  1891.         else if(font.align=='left'){
  1892.             align=(x*1)+(10*1)
  1893.         }
  1894.         else{
  1895.             align=(x*1)+(width-10);
  1896.         }
  1897.         var textAnchor="middle";
  1898.         if(font.align=='left'){
  1899.             textAnchor="start";
  1900.         }
  1901.         else if(font.align=='right'){
  1902.             textAnchor="end";
  1903.         }
  1904.         for(var i=0;i<textList.length;i++){
  1905.             textList[i].setAttributeNS(null,"x",align);
  1906.             textList[i].setAttributeNS(null,"text-anchor",textAnchor);
  1907.             
  1908.             
  1909.         }
  1910.         
  1911.     }
  1912. }
  1913.  
  1914. /**
  1915. *this method will pull out the font from the dummyText and then report it back
  1916. **/
  1917.  
  1918. SVGRenderer.prototype.getFont=function(shape){
  1919.  
  1920.     var font=new Object();
  1921.     font.size='';
  1922.     font.family='';
  1923.     font.color='';
  1924.     font.align='';
  1925.     font.italics='';
  1926.     font.bold='';
  1927.     //for backward compatibility. after 0.2 we will use "text:template";
  1928.     var element=document.getElementById("text:dummy"+shape.id);;
  1929.     if(!element){
  1930.         element=document.getElementById("text:template"+shape.id);
  1931.     }
  1932.     if(!element)
  1933.         return font;
  1934.     else{
  1935.         
  1936.         
  1937.         font.color=element.getAttributeNS(null,"fill");
  1938.         
  1939.         font.family=element.getAttributeNS(null,"font-family");
  1940.         
  1941.         font.size=element.getAttributeNS(null,"font-size");
  1942.         
  1943.         font.bold=element.getAttributeNS(null,"font-weight");
  1944.         
  1945.         font.italics=element.getAttributeNS(null,"font-style");;
  1946.         //todo for align!!!
  1947.         var align=element.getAttributeNS(null,"text-anchor");
  1948.         if(align=='middle')
  1949.             align='center';
  1950.         else if(align=='end')
  1951.             align='right';
  1952.         else
  1953.             align='left';
  1954.         font.align=align;
  1955.     
  1956.     }
  1957.     return font;    
  1958.  
  1959. }
  1960.  
  1961.  
  1962.  
  1963. SVGRenderer.prototype.getMarkup = function() {
  1964.   return this.container.innerHTML;
  1965. }
  1966. /**incase of svg the selection source comes back as path which resides in g/svg/path, 
  1967. **in order to return g we need to climb 2 levels
  1968. **/
  1969. SVGRenderer.prototype.getShapeFromEventSource=function(source){
  1970.     
  1971.     if(source){
  1972.         if(source.tagName=='text')
  1973.             return source.parentNode;
  1974.         else
  1975.             return source.parentNode.parentNode;
  1976.     }
  1977. }
  1978.  
  1979. /**
  1980. *append an attribute to the page cumulate draw specific
  1981. **/
  1982. SVGRenderer.prototype.appendPageAttribute=function(div,attribute){
  1983.     if(div){
  1984.         var svg=div.getElementsByTagName("svg")[0];
  1985.         svg.appendChild(attribute);
  1986.     }
  1987.  
  1988. }
  1989. /**
  1990. *get the actual data from within the richdraw div
  1991. **/
  1992. SVGRenderer.prototype.getRealData=function(){
  1993.     var xml=this.svgRoot.xml;
  1994.     var parser=new DOMParser(true);
  1995.     parser.preserveWhiteSpace=true;
  1996.     return parser.parseFromString(xml, "application/xml");  
  1997. }
  1998.  
  1999. /**
  2000. *return the response as a valid xml document
  2001. **/
  2002. SVGRenderer.prototype.getValidDocumentFromResponse=function(response){
  2003.     var parser=new DOMParser(true);
  2004.     parser.preserveWhiteSpace=true;
  2005.     return parser.parseFromString(response, "application/xml"); 
  2006. }
  2007.  
  2008. /**
  2009. *open the objects in .fmd file
  2010. **/
  2011. SVGRenderer.prototype.open=function(div){
  2012.     var nodes=div.getElementsByTagName("g");
  2013.     nodes=$A(nodes);
  2014.     for(var i=0;i<nodes.length;i++){
  2015.         this.svgRoot.appendChild(nodes[i]);
  2016.     }
  2017. }
  2018.  
  2019.